ES6
规定了对象属性枚举顺序。
1 | 9.1.12 [[OwnPropertyKeys]]() |
也就是说,Object的属性遍历按照:数字从小到大 -> 字符串创建顺序 -> Symbol 创建顺序 进行遍历。
举例
1 | x = {b:20, 3:2, [Symbol('A')]:2, a:100, 2:1} |
Chrome DevTools调用[[OwnPropertyKeys]]()
列出对象的所有属性。
Object.keys的枚举顺序
参考文章:5分钟彻底理解Object.keys
1 | x = {b:20, 3:2, [Symbol('A')]:2, a:100, 2:1} |
Object.keys
将Symbol
类型的属性过滤掉了。
当Object.keys函数使用参数O调用时,会执行以下步骤:
1. 将参数转换成Object类型的对象(ToObject(O))
Let obj be ? ToObject(O).
1 | Undefined: 抛出TypeError |
举例:
1 | new Number(123) |
1 | new String('test') |
2. 获取属性列表(EnumerableOwnPropertyNames(obj, “key”))
Let nameList be ? EnumerableOwnProperties(obj, “key”).
调用对象的内部方法OwnPropertyKeys
获得对象的ownKeys(List类型),然后声明变量properties(List类型),循环ownKeys将每个元素添加到properties列表中,最终将properties返回。
所以对于Object.keys(O)来说,内部方法OwnPropertyKeys
决定了属性列表的顺序。
3. 将List类型的属性列表properties转换为Array得到最终的结果
Return CreateArrayFromList(nameList).
将List类型转换成Array类型:
- 先声明一个变量array,值是一个空数组
- 循环属性列表,将每个元素添加到array中
- 将array返回
该顺序规则适用于其他API
- Object.entries
- Object.values
- for…in循环
- Object.getOwnPropertyNames
- Reflect.ownKeys
注意:以上API除了Reflect.ownKeys之外,其他API均会将Symbol类型的属性过滤掉。
ES规范
ECMAScript® 2015 Language Specification(ES6)